package vip.xiaonuo.miniapp.api.service;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import reactor.core.Reactor;
import reactor.event.Event;
import vip.xiaonuo.core.context.constant.ConstantContextHolder;
import vip.xiaonuo.core.exception.ServiceException;
import vip.xiaonuo.core.factory.PageFactory;
import vip.xiaonuo.core.pojo.httpclient.ReturnJson;
import vip.xiaonuo.core.util.DateUtils;
import vip.xiaonuo.facedoor.modular.constant.ApprovoedConstant;
import vip.xiaonuo.facedoor.modular.memberuser.entity.MemberUser;
import vip.xiaonuo.facedoor.modular.memberuser.mapper.MemberUserMapper;
import vip.xiaonuo.facedoor.modular.memberuser.param.MemberUserParam;
import vip.xiaonuo.facedoor.modular.memberuser.param.MiniAppMemberUserParam;
import vip.xiaonuo.facedoor.modular.memberuser.service.FacedoorMemberUserService;
import vip.xiaonuo.facedoor.modular.memberuser.service.MemberUserService;
import vip.xiaonuo.facedoor.modular.memberuser.vo.MemberUserPageVO;
import vip.xiaonuo.facedoor.modular.topic.EventTopic;
import vip.xiaonuo.facedoor.modular.visitor.entity.Visitor;
import vip.xiaonuo.facedoor.modular.visitor.service.VisitorService;
import vip.xiaonuo.miniapp.api.constant.VisitorConstant;
import vip.xiaonuo.miniapp.api.entity.MemberPermission;
import vip.xiaonuo.miniapp.api.entity.VisitorPermission;
import vip.xiaonuo.miniapp.api.mapper.MiniAppVisitorMapper;
import vip.xiaonuo.miniapp.api.miniapp.config.WxMaConfiguration;
import vip.xiaonuo.miniapp.api.miniappmemberuser.entity.MiniappMemberUser;
import vip.xiaonuo.miniapp.api.miniappmemberuser.mapper.MiniappMemberUserMapper;
import vip.xiaonuo.miniapp.api.miniappmemberuser.param.MiniappMemberUserParam;
import vip.xiaonuo.miniapp.api.miniappmemberuser.service.MiniappMemberUserService;
import vip.xiaonuo.miniapp.api.util.PageResult;
import vip.xiaonuo.miniapp.api.vo.*;
import vip.xiaonuo.sys.modular.org.entity.SysOrg;
import vip.xiaonuo.sys.modular.org.service.SysOrgService;
import vip.xiaonuo.sys.modular.pos.entity.SysPos;
import vip.xiaonuo.sys.modular.pos.service.SysPosService;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class MiniAppService {


    @Resource
    private MemberUserMapper mapper;

    @Resource
    private MiniappMemberUserMapper miniappMemberUserMapper;

    @Autowired
    private VisitorService visitorService;

    @Autowired
    private MiniAppVisitorMapper miniAppVisitorMapper;

    @Autowired
    private WxMaConfiguration wxMaConfiguration;

    @Autowired
    private MemberUserService memberService;

    @Autowired
    private FacedoorMemberUserService facedoorMemberUserService;

    @Autowired
    private MiniappMemberUserService miniappMemberUserService;

    @Autowired
    private SysOrgService sysOrgService;

    @Autowired
    private SysPosService posService;

    @Autowired
    private Reactor reactor;


    public String getCodeStr(String inviterPhone, Long id) {
        MemberUser invitorMember = this.getByPhone(inviterPhone);
        // 不是内部人员是访客
        if (invitorMember == null) {
            List<Visitor> lastByPhone = visitorService.list(new LambdaQueryWrapper<Visitor>().eq(Visitor::getStatus, "1").eq(ObjectUtil.isNotEmpty(inviterPhone), Visitor::getTel, inviterPhone)
                    .le(Visitor::getVisitStartDate, new Date()).ge(Visitor::getVisitEndDate, new Date()).eq(ObjectUtil.isNotEmpty(id), Visitor::getId, id));
            if (CollectionUtils.isEmpty(lastByPhone)) {
                return "";
            }
            List<Long> ids = lastByPhone.stream().map(Visitor::getId).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(ids)) {
                return "";
            }
            List<VisitorPermission> visitorPermissions = miniAppVisitorMapper.selectVisitorDevicePermission(ids);
            StringBuffer stringBuffer = visitorCode(lastByPhone, visitorPermissions);
            return stringBuffer.toString();
        } // 返回人员数据
        List<MemberPermission> memberPermissions = miniAppVisitorMapper.selectMemberDevicePermission(invitorMember.getId());
        StringBuffer stringBuffer = memberCode(invitorMember, memberPermissions);
        return stringBuffer.toString();
    }

    private static StringBuffer memberCode(MemberUser invitorMember, List<MemberPermission> memberPermissions) {
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("M_1")
                .append(invitorMember.getId()).append("@T_")
                .append(DateUtils.formatDate(DateUtils.addTimeMillis(new Date(), 300000), "yyyyMMddHHmmss"))
//                .append("@Z_1")
        ;
        if (CollectionUtil.isEmpty(memberPermissions)) {
            return stringBuffer;
        }
        Map<String, List<MemberPermission>> permGroupMap = memberPermissions.stream().collect(Collectors.groupingBy(MemberPermission::getCode));
        permGroupMap.forEach((code, prems) -> {
            stringBuffer.append("@").append(code).append("_");
            MemberPermission memberPermission = prems.get(0);
            if (memberPermission != null) {
                if (ObjectUtil.equal(memberPermission.getDeviceRole(), 1)) {
                    stringBuffer.append(99);
                } else {
                    List<String> collect = prems.stream().map(MemberPermission::getHandFloor).distinct().collect(Collectors.toList());
                    if (CollectionUtil.isNotEmpty(collect)) {
                        stringBuffer.append(StringUtils.join(collect, ","));
                    }
                }
            }

        });
        return stringBuffer;
    }

    @NotNull
    private static StringBuffer visitorCode(List<Visitor> visitor, List<VisitorPermission> visitorPermissions) {
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("V_2")
                .append(visitor.get(0).getId()).append("@T_")
                .append(DateUtils.formatDate(DateUtils.addTimeMillis(new Date(), 300000), "yyyyMMddHHmmss"))
//                .append("@Z_1")
        ;
        if (CollectionUtil.isEmpty(visitorPermissions)) {
            return stringBuffer;
        }
        Map<String, List<VisitorPermission>> permGroupMap = visitorPermissions.stream().collect(Collectors.groupingBy(VisitorPermission::getCode));
        permGroupMap.forEach((code, prems) -> {
            stringBuffer.append("@").append(code).append("_");
            VisitorPermission visitorPermission = prems.get(0);
            if (visitorPermission != null) {
                if (ObjectUtil.equal(visitorPermission.getDeviceRole(), 1)) {
                    stringBuffer.append(99);
                } else {
                    List<String> collect = prems.stream().map(VisitorPermission::getHandFloor).distinct().collect(Collectors.toList());
                    if (CollectionUtil.isNotEmpty(collect)) {
                        stringBuffer.append(StringUtils.join(collect, ","));
                    }
                }
            }

        });
        return stringBuffer;
    }


    /**
     * 内部人员提交审批
     *
     * @param memberApiSaveVo 提交审批
     */
    public void saveMember(MemberApiSaveVo memberApiSaveVo) {

        Boolean registerUserFromMiniApp = ConstantContextHolder.getSysConfig("REGISTER_USER_FROM_MINI_APP_APPROVAL", Boolean.class, true);
        if (registerUserFromMiniApp) {
            if (memberApiSaveVo.getId() != null) {
                MiniappMemberUser byId = miniappMemberUserService.getById(memberApiSaveVo.getId());
                if (byId != null) {
                    checkMemberUser(memberApiSaveVo);
                    checkMiniAppMemberUser(memberApiSaveVo);
                    BeanUtils.copyProperties(memberApiSaveVo, byId);
                    // 3 未审批
                    byId.setStatus(3);
                    miniappMemberUserService.updateById(byId);
                }
            } else {
                checkMemberUser(memberApiSaveVo);
                checkMiniAppMemberUser(memberApiSaveVo);
                MiniappMemberUser memberUser = new MiniappMemberUser();
                BeanUtils.copyProperties(memberApiSaveVo, memberUser);
                // 3 未审批
                memberUser.setStatus(3);
                miniappMemberUserService.save(memberUser);
            }
        } else {
            // 不需要审批
            if (memberApiSaveVo.getId() != null) {
                MiniappMemberUser byId = miniappMemberUserService.getById(memberApiSaveVo.getId());
                if (byId != null) {
                    checkMemberUser(memberApiSaveVo);
                    checkMiniAppMemberUser(memberApiSaveVo);
                    BeanUtils.copyProperties(memberApiSaveVo, byId);
                    // 3 未审批
                    byId.setStatus(1);
                    miniappMemberUserService.updateById(byId);
                    MiniappMemberUserParam memberUserParam = new MiniappMemberUserParam();
                    BeanUtils.copyProperties(byId, memberUserParam);
                    miniappMemberUserService.edit(memberUserParam);
                }
            } else {
                checkMemberUser(memberApiSaveVo);
                checkMiniAppMemberUser(memberApiSaveVo);
                MiniappMemberUser memberUser = new MiniappMemberUser();
                BeanUtils.copyProperties(memberApiSaveVo, memberUser);
                // 3 未审批
                memberUser.setStatus(1);
                miniappMemberUserService.save(memberUser);
                MiniappMemberUserParam memberUserParam = new MiniappMemberUserParam();
                BeanUtils.copyProperties(memberUser, memberUserParam);
                miniappMemberUserService.edit(memberUserParam);
            }
        }


    }


    public void approval(MemberApprovalVo approvalVo) {
        MiniappMemberUser miniappMemberUser = miniappMemberUserService.getById(approvalVo.getMiniappMemberId());
        if (miniappMemberUser == null) {
            throw new ServiceException(500, "找不到当前录入会员信息！");
        }
        if (!ObjectUtil.equal(miniappMemberUser.getStatus(), 3)) {
            throw new ServiceException(500, "不在未审批状态不可提交审核！");
        }
        // 审批拒绝
        if (ObjectUtil.equal(approvalVo.getStatus(), 2)) {
            miniappMemberUser.setRemarks(approvalVo.getRemark());
            miniappMemberUser.setStatus(2);
            miniappMemberUserService.updateById(miniappMemberUser);
        }
        // 审批通过
        if (ObjectUtil.equal(approvalVo.getStatus(), 1)) {
            miniappMemberUser.setStatus(1);
            MemberUser existMember = memberService.getOne(new LambdaQueryWrapper<MemberUser>().eq(MemberUser::getMiniAppMemberId, miniappMemberUser.getId()));
            // 修改
            if (existMember != null) {
                Long memberUserId = existMember.getId();
                MemberUserParam memberUser = new MemberUserParam();
                BeanUtils.copyProperties(miniappMemberUser, existMember);
                BeanUtils.copyProperties(existMember, memberUser);
                memberUser.setId(memberUserId);
                facedoorMemberUserService.edit(memberUser);
                miniappMemberUserService.updateById(miniappMemberUser);
                return;
            }

            // 新增
            MemberUserParam memberUser = new MemberUserParam();
            BeanUtils.copyProperties(miniappMemberUser, memberUser);
            memberUser.setId(null);
            memberUser.setMiniAppMemberId(miniappMemberUser.getId());
            miniappMemberUserService.updateById(miniappMemberUser);
            facedoorMemberUserService.add(memberUser);
        }
    }


    /**
     * 内部人员列表
     *
     * @param memberApiQueryVo 查询参数
     */

    public Page<MiniappMemberUser> miniappMemberList(MemberApiQueryVo memberApiQueryVo) {
        MemberUser memberUser = memberService.getOne(new LambdaQueryWrapper<MemberUser>().eq(MemberUser::getTel, memberApiQueryVo.getLoginTel()));
        if (memberUser == null) {
            throw new ServiceException(500, "您还不是内部员工！");
        }
        if (memberApiQueryVo.getId() != null) {
            return miniappMemberUserMapper.page(PageFactory.defaultPage(), memberApiQueryVo);
        }
        // 管理员查看全部
        if (ObjectUtil.equal(memberUser.getMiniAppAdmin(), 0)) {
            return miniappMemberUserMapper.page(PageFactory.defaultPage(), memberApiQueryVo);
        }
        Boolean isOrgOrXz = Boolean.FALSE;
        Long posId = memberUser.getPosId();
        Long orgId = memberUser.getOrgId();
        if (orgId == null && posId == null) {
            return new Page<>();
        }

        if (posId != null) {
            SysPos pos = posService.getById(posId);
            // 行政职位
            if (ObjectUtil.equal("XZZZ", pos.getCode())) {
                isOrgOrXz = Boolean.TRUE;
                // 组织参数权限加进去
                memberApiQueryVo.setOrgId(memberUser.getOrgId());
            }
        }

        if (orgId != null) {
            // 行政组织可查看全部
            SysOrg sysOrg = sysOrgService.getById(orgId);
            if (ObjectUtil.equal(sysOrg.getCode(), "xingzheng_group")) {
                isOrgOrXz = Boolean.TRUE;
                // 组织参数权限加进去
                memberApiQueryVo.setOrgId(null);
            }
        }
        if (!isOrgOrXz) {
            return new Page<>();
        }
        return miniappMemberUserMapper.page(PageFactory.defaultPage(), memberApiQueryVo);
    }


    public MiniappMemberUser detail(MemberApiDetailVo memberApiDetailVo) {
        MiniappMemberUser one = miniappMemberUserMapper.getOne(memberApiDetailVo);
        if (one == null) {
            // 内部人员未在小程序端录入
            MemberUser memberUser = memberService.getOne(new LambdaQueryWrapper<MemberUser>().eq(MemberUser::getTel, memberApiDetailVo.getLoginTel()));
            if (memberUser != null) {
                // 先录入到小程序表中 状态是审核通过
                one = new MiniappMemberUser();
                BeanUtils.copyProperties(memberUser, one);
                one.setStatus(1);
                one.setId(null);
                miniappMemberUserMapper.insert(one);
                memberUser.setMiniAppMemberId(one.getId());
                memberService.updateById(memberUser);
                return miniappMemberUserMapper.getOne(memberApiDetailVo);
            }
        }
        return miniappMemberUserMapper.getOne(memberApiDetailVo);
    }


    private void checkMemberUser(MemberApiSaveVo memberApiSaveVo) {
        MemberUser memberUser = null;
        if (memberApiSaveVo.getId() != null) {
            memberUser = memberService.getOne(new LambdaQueryWrapper<MemberUser>().eq(MemberUser::getMiniAppMemberId, memberApiSaveVo.getId()));

        }
        if (memberUser == null) {
            List<MemberUser> jobNums = memberService.list(new LambdaQueryWrapper<MemberUser>().eq(MemberUser::getJobNum, memberApiSaveVo.getJobNum()));
            if (CollectionUtil.isNotEmpty(jobNums)) {
                throw new ServiceException(500, "工号不能重复!");
            }
            List<MemberUser> tels = memberService.list(new LambdaQueryWrapper<MemberUser>().eq(MemberUser::getTel, memberApiSaveVo.getTel()));
            if (CollectionUtil.isNotEmpty(tels)) {
                throw new ServiceException(500, "手机号码不能重复!");
            }

            if (StringUtils.isNotBlank(memberApiSaveVo.getIcCard())) {
                List<MemberUser> icCards = memberService.list(new LambdaQueryWrapper<MemberUser>().eq(MemberUser::getIcCard, memberApiSaveVo.getIcCard()));
                if (CollectionUtil.isNotEmpty(icCards)) {
                    throw new ServiceException(500, "卡号不能重复!");
                }
            }
            if (StringUtils.isNotBlank(memberApiSaveVo.getIdCard())) {
                List<MemberUser> icCards = memberService.list(new LambdaQueryWrapper<MemberUser>().eq(MemberUser::getIdCard, memberApiSaveVo.getIdCard()));
                if (CollectionUtil.isNotEmpty(icCards)) {
                    throw new ServiceException(500, "身份证号不能重复!");
                }
            }
        } else {
            List<MemberUser> jobNums = memberService.list(new LambdaQueryWrapper<MemberUser>().eq(MemberUser::getJobNum, memberApiSaveVo.getJobNum()).ne(MemberUser::getId, memberUser.getId()));
            if (CollectionUtil.isNotEmpty(jobNums)) {
                throw new ServiceException(500, "工号不能重复!");
            }
            List<MemberUser> tels = memberService.list(new LambdaQueryWrapper<MemberUser>().eq(MemberUser::getTel, memberApiSaveVo.getTel()).ne(MemberUser::getId, memberUser.getId()));
            if (CollectionUtil.isNotEmpty(tels)) {
                throw new ServiceException(500, "手机号码不能重复!");
            }

            if (StringUtils.isNotBlank(memberApiSaveVo.getIcCard())) {
                List<MemberUser> icCards = memberService.list(new LambdaQueryWrapper<MemberUser>().eq(MemberUser::getIcCard, memberApiSaveVo.getIcCard()).ne(MemberUser::getId, memberUser.getId()));
                if (CollectionUtil.isNotEmpty(icCards)) {
                    throw new ServiceException(500, "卡号不能重复!");
                }
            }
            if (StringUtils.isNotBlank(memberApiSaveVo.getIdCard())) {
                List<MemberUser> icCards = memberService.list(new LambdaQueryWrapper<MemberUser>().eq(MemberUser::getIdCard, memberApiSaveVo.getIdCard()).ne(MemberUser::getId, memberUser.getId()));
                if (CollectionUtil.isNotEmpty(icCards)) {
                    throw new ServiceException(500, "身份证号不能重复!");
                }
            }
        }

    }

    private void checkMiniAppMemberUser(MemberApiSaveVo memberApiSaveVo) {
        MiniappMemberUser miniappMemberUser = null;
        if (memberApiSaveVo.getId() != null) {
            miniappMemberUser = miniappMemberUserService.getById(memberApiSaveVo.getId());
        }
        if (miniappMemberUser == null) {
            List<MiniappMemberUser> jobNums = miniappMemberUserService.list(new LambdaQueryWrapper<MiniappMemberUser>().in(MiniappMemberUser::getStatus, 1, 3).eq(MiniappMemberUser::getJobNum, memberApiSaveVo.getJobNum()));
            if (CollectionUtil.isNotEmpty(jobNums)) {
                throw new ServiceException(500, "工号不能重复!");
            }
            List<MiniappMemberUser> tels = miniappMemberUserService.list(new LambdaQueryWrapper<MiniappMemberUser>().in(MiniappMemberUser::getStatus, 1, 3).eq(MiniappMemberUser::getTel, memberApiSaveVo.getTel()));
            if (CollectionUtil.isNotEmpty(tels)) {
                throw new ServiceException(500, "手机号码不能重复!");
            }

            if (StringUtils.isNotBlank(memberApiSaveVo.getIcCard())) {
                List<MiniappMemberUser> icCards = miniappMemberUserService.list(new LambdaQueryWrapper<MiniappMemberUser>().in(MiniappMemberUser::getStatus, 1, 3).eq(MiniappMemberUser::getIcCard, memberApiSaveVo.getIcCard()));
                if (CollectionUtil.isNotEmpty(icCards)) {
                    throw new ServiceException(500, "卡号不能重复!");
                }
            }
            if (StringUtils.isNotBlank(memberApiSaveVo.getIdCard())) {
                List<MiniappMemberUser> icCards = miniappMemberUserService.list(new LambdaQueryWrapper<MiniappMemberUser>().in(MiniappMemberUser::getStatus, 1, 3).eq(MiniappMemberUser::getIdCard, memberApiSaveVo.getIdCard()));
                if (CollectionUtil.isNotEmpty(icCards)) {
                    throw new ServiceException(500, "身份证号不能重复!");
                }
            }
        } else {
            List<MiniappMemberUser> jobNums = miniappMemberUserService.list(new LambdaQueryWrapper<MiniappMemberUser>().in(MiniappMemberUser::getStatus, 1, 3)
                    .eq(MiniappMemberUser::getJobNum, memberApiSaveVo.getJobNum()).ne(MiniappMemberUser::getId, memberApiSaveVo.getId()));
            if (CollectionUtil.isNotEmpty(jobNums)) {
                throw new ServiceException(500, "工号不能重复!");
            }
            List<MiniappMemberUser> tels = miniappMemberUserService.list(new LambdaQueryWrapper<MiniappMemberUser>().in(MiniappMemberUser::getStatus, 1, 3)
                    .eq(MiniappMemberUser::getTel, memberApiSaveVo.getTel()).ne(MiniappMemberUser::getId, memberApiSaveVo.getId()));
            if (CollectionUtil.isNotEmpty(tels)) {
                throw new ServiceException(500, "手机号码不能重复!");
            }

            if (StringUtils.isNotBlank(memberApiSaveVo.getIcCard())) {
                List<MiniappMemberUser> icCards = miniappMemberUserService.list(new LambdaQueryWrapper<MiniappMemberUser>().in(MiniappMemberUser::getStatus, 1, 3)
                        .eq(MiniappMemberUser::getIcCard, memberApiSaveVo.getIcCard()).ne(MiniappMemberUser::getId, memberApiSaveVo.getId()));
                if (CollectionUtil.isNotEmpty(icCards)) {
                    throw new ServiceException(500, "卡号不能重复!");
                }
            }
            if (StringUtils.isNotBlank(memberApiSaveVo.getIdCard())) {
                List<MiniappMemberUser> icCards = miniappMemberUserService.list(new LambdaQueryWrapper<MiniappMemberUser>().in(MiniappMemberUser::getStatus, 1, 3)
                        .eq(MiniappMemberUser::getIdCard, memberApiSaveVo.getIdCard()).ne(MiniappMemberUser::getId, memberApiSaveVo.getId()));
                if (CollectionUtil.isNotEmpty(icCards)) {
                    throw new ServiceException(500, "身份证号不能重复!");
                }
            }
        }

    }


    public ReturnJson getAllOrgs(String name) {
        ReturnJson returnJson = new ReturnJson();
        List<SysOrg> member_group = sysOrgService
                .list(new LambdaQueryWrapper<SysOrg>().like(StringUtils.isNotBlank(name), SysOrg::getName, name).eq(SysOrg::getType, 1)
                        .eq(SysOrg::getStatus, 0).ne(SysOrg::getCode, "member_group").eq(SysOrg::getShowInMiniApp, 1).orderByAsc(SysOrg::getSort));
        returnJson.success("data", member_group);
        return returnJson;
    }

    public List<SysPos> getAllPos(String name) {
        return posService.list(new LambdaQueryWrapper<SysPos>().like(StringUtils.isNotBlank(name), SysPos::getName, name).eq(SysPos::getStatus, 0));
    }


    public ReturnJson saveAndApproved(VisitorApiSaveVO visitorApiVO) throws Exception {
        ReturnJson returnJson = new ReturnJson();
        SysOrg visitor_group = sysOrgService.getOne(new LambdaQueryWrapper<SysOrg>().eq(SysOrg::getCode, "miniapp_group"));
        if (visitor_group == null) {
            returnJson.failed("result", "找不到默认的访客组！");
            return returnJson;
        }

        MemberUser invitorMember = this.getByPhone(visitorApiVO.getInviterPhone());
        SysOrg sysOrg = sysOrgService.getById(invitorMember.getOrgId());

        Visitor visitor = new Visitor();

        BeanUtils.copyProperties(visitorApiVO, visitor);

        // 直接审批通过
        visitor.setStatus(VisitorConstant.EXAMINATION_PASSD).setVisitStartDate(visitorApiVO.getVisitDate())
                .setVisitEndDate(visitorApiVO.getVisitTime()).setOrgId(visitor_group.getId()).setCompanyId(sysOrg.getId())
                .setCompanyName(sysOrg.getName()).setSource(2).setInviterId(invitorMember.getId())
                .setInviterName(invitorMember.getName()).setApprovalId(invitorMember.getId());
        visitorService.save(visitor);
        returnJson.success("id", visitor.getId());
        returnJson.success("inviteName",invitorMember.getName());

        // 通知设备做新增访客处理
        reactor.notify(EventTopic.VISITOR_MINIAPP_ADD, Event.wrap(visitor.getId()));

        return returnJson;
    }

    public void sendMessage(Long visitorId){
        reactor.notify(EventTopic.VISITOR_MINIAPP_SEND_MSG, Event.wrap(visitorId));
    }

    public MemberUser getByPhone(String tel) {
        if (StringUtils.isBlank(tel)) {
            return null;
        }
        return memberService.getOne(new LambdaQueryWrapper<MemberUser>().eq(MemberUser::getTel, tel));
    }

    public ReturnJson getMemberStairs(String inviterPhone) {
        ReturnJson returnJson = new ReturnJson();
        MemberUser invitorMember = this.getByPhone(inviterPhone);
        // 不是内部人员是访客
        if (invitorMember == null) {
            List<Visitor> lastByPhone = visitorService.list(new LambdaQueryWrapper<Visitor>().eq(Visitor::getTel, inviterPhone)
                    .le(Visitor::getVisitStartDate, new Date()).ge(Visitor::getVisitEndDate, new Date()));
            if (CollectionUtils.isEmpty(lastByPhone)) {
                returnJson.success("data", new ArrayList<>());
                return returnJson;
            }
            List<Long> ids = lastByPhone.stream().map(Visitor::getId).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(ids)) {
                returnJson.success("data", new ArrayList<>());
                return returnJson;
            }
            List<IdNameBar> idNameBars = miniAppVisitorMapper.selectAllStaris(ids);
            // 返回访客列表
            returnJson.success("data", idNameBars);
            return returnJson;
        }
        // 返回人员数据
        returnJson.success("data", miniAppVisitorMapper.selectAllDeviceName(invitorMember.getId()));
        return returnJson;
    }

    private void memberDevice(ReturnJson returnJson, MemberUser invitorMember) {
        if (invitorMember.getOrgId() == null) {
            returnJson.success("data", new ArrayList<>());
            return;
        }
        returnJson.success("data", miniAppVisitorMapper.getMemberDeviceIdNames(Collections.singletonList(invitorMember.getId())));
    }

    private void visitorDevice(String tel, ReturnJson returnJson) {
        List<Visitor> lastByPhone = visitorService.list(new LambdaQueryWrapper<Visitor>().eq(Visitor::getTel, tel).le(Visitor::getVisitStartDate, new Date()).ge(Visitor::getVisitEndDate, new Date()));
        List<Long> collect = lastByPhone.stream().map(Visitor::getId).collect(Collectors.toList());
        returnJson.success("data", collect.isEmpty() ? null : miniAppVisitorMapper.getOffceDeviceIdNames(collect));
    }

    public ReturnJson getMemberDevice(String inviterPhone) {
        ReturnJson returnJson = new ReturnJson();
        MemberUser invitorMember = this.getByPhone(inviterPhone);
        // 不是内部人员可能是访客
        if (invitorMember == null) {
            visitorDevice(inviterPhone, returnJson);
            return returnJson;
        }
        memberDevice(returnJson, invitorMember);
        return returnJson;
    }

    public ReturnJson save(VisitorApiSaveVO visitorApiVO) throws Exception {
        SysOrg miniapp_group = sysOrgService.getOne(new LambdaQueryWrapper<SysOrg>().eq(SysOrg::getCode, "miniapp_group"));
        if (miniapp_group == null) {
            log.error("小程序组不存在");
            ReturnJson returnJson = new ReturnJson();
            returnJson.failed("id", null);
            returnJson.setMsg("小程序组不存在！");
            return returnJson;
        }

        SysOrg sysOrg = sysOrgService.getById(visitorApiVO.getVisitorOrgId());
        if (sysOrg == null) {
            log.error("被访组织信息不存在!");
            ReturnJson returnJson = new ReturnJson();
            returnJson.failed("id", null);
            returnJson.setMsg("被访组织信息不存在！");
            return returnJson;
        }

        MemberUser invitorMember = this.getByPhone(visitorApiVO.getInviterPhone());
        Visitor visitor = new Visitor();
        BeanUtils.copyProperties(visitorApiVO, visitor);
        visitor.setVisitStartDate(visitorApiVO.getVisitDate());
        visitor.setVisitEndDate(visitorApiVO.getVisitTime());
        visitor.setCompanyId(visitorApiVO.getVisitorOrgId());
        visitor.setCompanyName(sysOrg.getName());
        visitor.setOrgId(miniapp_group.getId());
        visitor.setIssuanceOfVouchers(1);
        visitor.setSource(2);
        if (invitorMember != null) {
            visitor.setInviterId(invitorMember.getId());
            visitor.setInviterName(invitorMember.getName());
        }
        String approval = ConstantContextHolder.getApprovalMiniApp();
        switch (approval) {
            // 无需审批 默认走组织的权限
            case ApprovoedConstant.NO:
                visitor.setStatus(VisitorConstant.EXAMINATION_PASSD);
                visitorService.save(visitor);
                // 通知设备做新增访客处理
                reactor.notify(EventTopic.VISITOR_MINIAPP_ADD, Event.wrap(visitor.getId()));
                break;
            case ApprovoedConstant.USER:
                if (invitorMember == null) {
                    log.error("未填写被访人信息!【{}】", JSON.toJSONString(visitorApiVO));
                    ReturnJson returnJson = new ReturnJson();
                    returnJson.failed("id", null);
                    returnJson.setMsg("未填写被访人信息！");
                    return returnJson;
                }
                // 默认未审批状态
                visitor.setStatus(VisitorConstant.NOT_APPROVED);
                visitorService.save(visitor);
                break;
            case ApprovoedConstant.ORG:
                // 默认未审批状态
                visitor.setStatus(VisitorConstant.NOT_APPROVED);
                visitorService.save(visitor);
                break;
            case ApprovoedConstant.USE_OR_ORG:
                // 默认未审批状态
                visitor.setStatus(VisitorConstant.NOT_APPROVED);
                visitorService.save(visitor);
                break;
        }
        ReturnJson returnJson = new ReturnJson();
        returnJson.success("id", visitor.getId());
        return returnJson;
    }

    public ReturnJson approval(VisitorApprovalVo approvalVo) {
        ReturnJson returnJson = new ReturnJson();
        Visitor visitor = visitorService.getById(approvalVo.getVisitorId());
        if (visitor == null) {
            returnJson.failed("result", "找不到访客信息");
            return returnJson;
        }
        if (!visitor.getStatus().equals(VisitorConstant.NOT_APPROVED)) {
            returnJson.failed("result", "该访客已经过期或者审核完成请进行核查！");
            return returnJson;
        }
        if (approvalVo.getStatus().equals(VisitorConstant.EXAMINATION_PASSD)) {
            if (visitor.getVisitEndDate().before(new Date())) {
                returnJson.failed("result", "访问时间已经过期！不可审批通过！");
                return returnJson;
            }
            visitor.setIssuanceOfVouchers(0);
            // 通知设备做新增访客处理
            reactor.notify(EventTopic.VISITOR_MINIAPP_ADD, Event.wrap(visitor.getId()));
        } else {
            visitor.setIssuanceOfVouchers(1);
        }
        MemberUser memberUser = memberService.getOne(new LambdaQueryWrapper<MemberUser>().eq(MemberUser::getTel, approvalVo.getApprovalPhone()));
        if (memberUser == null) {
            returnJson.failed("result", "找不到审核人信息！");
            return returnJson;
        }
        visitor.setStatus(approvalVo.getStatus());
        visitor.setApprovalRemake(approvalVo.getApprovalRemake());
        visitor.setApprovalId(memberUser.getId());
        visitorService.updateById(visitor);
        returnJson.success("result", "success");
        return returnJson;
    }

    public ReturnJson login(String code) {
        ReturnJson returnJson = new ReturnJson();
        final WxMaService wxService = wxMaConfiguration.getMaService();
        try {
            WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(code);
            log.info("登录接口获取SessionKey[{}]", session.getSessionKey());
            log.info("登录接口获取OpenId[{}]", session.getOpenid());
            returnJson.success("result", session);
            return returnJson;
        } catch (WxErrorException e) {
            log.error(e.getMessage(), e);
            log.error("登录接口失败[{}]", e.getMessage());
            returnJson.failed("result", ExceptionUtils.getMessage(e));
            return returnJson;
        }
    }

    public ReturnJson getPhone(String sessionKey, String encryptedData, String ivStr) {
        Assert.notNull(sessionKey, "sessionKey不能为null");
        Assert.notNull(encryptedData, "encryptedData不能为null");
        Assert.notNull(ivStr, "ivStr不能为null");
        ReturnJson returnJson = new ReturnJson();
        final WxMaService wxService = wxMaConfiguration.getMaService();
        WxMaPhoneNumberInfo phoneNoInfo = null;
        phoneNoInfo = wxService.getUserService().getPhoneNoInfo(sessionKey, encryptedData, ivStr);
        if (phoneNoInfo != null) {
            returnJson.success("phoneNumber", phoneNoInfo.getPhoneNumber());
            return returnJson;
        } else {
            log.info("解密用户手机号失败[{}]", phoneNoInfo);
            returnJson.failed("phoneNumber", "");
            returnJson.setMsg("解密失败！");
            return returnJson;
        }
    }

    public ReturnJson login(VisitorAdminLoginVO login) {
        ReturnJson returnJson = new ReturnJson();
        Boolean registerUserFromMiniApp = ConstantContextHolder.getSysConfig("REGISTER_USER_FROM_MINI_APP", Boolean.class, true);
        returnJson.setData("registerUserFromMiniApp", registerUserFromMiniApp);
        MemberUser dbMember = this.getByPhone(login.getPhone());
        if (dbMember == null) {
            returnJson.setData("memberId", null);
            returnJson.failed("token", "DEWODFACEDOOR");
            returnJson.setData("approval", Boolean.FALSE);
            returnJson.setMsg("找不到用户信息! 请验证用户名是否正确!");
            return returnJson;
        }
        returnJson.setData("memberId", dbMember.getId());
        returnJson.success("token", "DEWODFACEDOOR");
        // 管理员查看全部
        if (ObjectUtil.equal(dbMember.getMiniAppAdmin(), 0)) {
            returnJson.setData("approval", Boolean.TRUE);
            return returnJson;
        }
        // 当前组织审批
        Long orgId = dbMember.getOrgId();
        Long posId = dbMember.getPosId();
        if (orgId == null && posId == null) {
            returnJson.setData("approval", Boolean.FALSE);
            return returnJson;
        }

        if (posId != null) {
            SysPos pos = posService.getById(posId);
            // 行政职位
            if (ObjectUtil.equal("XZZZ", pos.getCode())) {
                returnJson.setData("approval", Boolean.TRUE);
                return returnJson;
            }
        }

        // 行政组织
        if (orgId != null) {
            SysOrg sysOrg = sysOrgService.getById(orgId);
            if (ObjectUtil.equal(sysOrg.getCode(), "xingzheng_group")) {
                returnJson.setData("approval", Boolean.TRUE);
                return returnJson;
            }
        }
        returnJson.setData("approval", Boolean.FALSE);
        return returnJson;
    }

    public ReturnJson list(VisitorApiRequestVO visitorApiRequestVO) {
        ReturnJson returnJson = new ReturnJson();
        VisitorApiResponseVO visitorApiResponseVO = new VisitorApiResponseVO();
        if (!CollectionUtils.isEmpty(visitorApiRequestVO.getStatus())) {
            visitorApiResponseVO.setStatus(String.join(",", visitorApiRequestVO.getStatus()));
        }

        // 审批列表查看
        if (StringUtils.isNotBlank(visitorApiRequestVO.getInviterPhone())) {
            // 获取当前内部人员
            MemberUser memberUser = memberService.getOne(new LambdaQueryWrapper<MemberUser>().eq(MemberUser::getTel, visitorApiRequestVO.getInviterPhone()));
            if (memberUser == null) {
                returnJson.failed("result", null);
                returnJson.setMsg("找不到用户信息! 请验证用户名是否正确!");
                return returnJson;
            }
            // 小程序管理员全部能看
            if (ObjectUtil.equal(memberUser.getMiniAppAdmin(), 0)) {
                visitorApiRequestVO.setInviterPhone(null);
                visitorApiRequestVO.setCompanyId(null);
            } else {
                String approval = ConstantContextHolder.getApprovalMiniApp();
                switch (approval) {
                    // 无需审批
                    case ApprovoedConstant.NO:
                        if (!ObjectUtil.equal(memberUser.getMiniAppAdmin(), 0)) {
                            returnJson.success("result", null);
                            return returnJson;
                        } else {
                            visitorApiRequestVO.setInviterPhone(null);
                        }
                        break;

                    // 被访人权限  被访人可看 使用前台传入邀请人手机号码参数
                    case ApprovoedConstant.USER:
                        break;
                    // 组织权限 不带被访人 使用前台传入请邀人组织参数
                    case ApprovoedConstant.ORG:
                        Boolean isOrgOrXz = Boolean.FALSE;
                        // 当前组织审批
                        Long orgId = memberUser.getOrgId();
                        Long posId = memberUser.getPosId();
                        if (orgId == null && posId == null) {
                            returnJson.success("result", null);
                            return returnJson;
                        }

                        if (posId != null) {
                            SysPos pos = posService.getById(posId);
                            // 行政职位
                            if (ObjectUtil.equal("XZZZ", pos.getCode())) {
                                isOrgOrXz = Boolean.TRUE;
                                // 组织参数权限加进去
                                visitorApiRequestVO.setCompanyId(memberUser.getOrgId());
                                visitorApiRequestVO.setInviterPhone(null);
                            }
                        }

                        // 行政组织
                        if (orgId != null) {
                            SysOrg sysOrg = sysOrgService.getById(orgId);
                            if (ObjectUtil.equal(sysOrg.getCode(), "xingzheng_group")) {
                                isOrgOrXz = Boolean.TRUE;
                                visitorApiRequestVO.setInviterPhone(null);
                                visitorApiRequestVO.setCompanyId(null);
                            }
                        }
                        if (!isOrgOrXz) {
                            returnJson.success("result", null);
                            return returnJson;
                        }

                        break;

                    // 用户职位为行政人员 或者 用户组为行政组  使用邀请人组织参数
                    case ApprovoedConstant.USE_OR_ORG:
                        userOrOrg(visitorApiRequestVO, visitorApiResponseVO, memberUser);
                        break;
                }
            }
        }

        BeanUtils.copyProperties(visitorApiRequestVO, visitorApiResponseVO);
        Page<VisitorApiResponseVO> page = miniAppVisitorMapper.findApiList(new Page<>(visitorApiRequestVO.getPageNo(), visitorApiRequestVO.getPageSize()), visitorApiResponseVO);
        PageResult<VisitorApiResponseVO> pageResult = new PageResult<>();
        pageResult.setList(page.getRecords());
        pageResult.setPageNo((int) page.getCurrent());
        pageResult.setCount(page.getTotal());
        pageResult.setPageSize((int) page.getSize());
        returnJson.success("result", pageResult);
        return returnJson;
    }

    private void userOrOrg(VisitorApiRequestVO visitorApiRequestVO, VisitorApiResponseVO visitorApiResponseVO, MemberUser memberUser) {
        Long posId = memberUser.getPosId();
        if (posId != null) {
            SysPos pos = posService.getById(posId);
            // 行政职位
            if (ObjectUtil.equal("XZZZ", pos.getCode())) {
                // 组织参数权限加进去
                visitorApiResponseVO.setIsUserOrOrg(1);
                visitorApiRequestVO.setCompanyId(memberUser.getOrgId());
                visitorApiRequestVO.setInviterPhone(null);
            }
        }

        Long orgId = memberUser.getOrgId();
        if (orgId != null) {
            SysOrg currentOrg = sysOrgService.getById(orgId);
            if (ObjectUtil.equal(currentOrg.getCode(), "xingzheng_group")) {
                visitorApiResponseVO.setIsUserOrOrg(null);
                // 组织参数权限加进去
                visitorApiRequestVO.setCompanyId(null);
                visitorApiRequestVO.setInviterPhone(null);
            }
        }
    }

    public ReturnJson memberList(String name, String phone, Long orgIds) {
        ReturnJson returnJson = new ReturnJson();
        List<MemberUserPageVO> list = mapper.findMiniappList(new MiniAppMemberUserParam().setName(name).setTel(phone).setOrgId(orgIds).setMiniApp(1));
//        List<MemberUser> list = memberService.list(new LambdaQueryWrapper<MemberUser>().like(StringUtils.isNotBlank(name), MemberUser::getName, name)
//                .like(StringUtils.isNotBlank(phone), MemberUser::getTel, phone)
//                .isNotNull(MemberUser::getTel).eq(orgIds != null, MemberUser::getOrgId, orgIds));
        returnJson.success("data", list);
        return returnJson;
    }
}
